Conversation
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (17)
📝 WalkthroughWalkthroughAdds a new Email Logs API surface: Mailtrap::EmailLogsAPI with list/get methods and cursor pagination, DTOs for messages, events, and event details, example script, lib require, VCR fixtures, RSpec tests, and a CHANGELOG entry. Changes
Sequence Diagram(s)sequenceDiagram
actor Client
participant EmailLogsAPI
participant HTTPClient as HTTP Client
participant APIServer as API Server
participant Mapper as Response Mapper
Client->>EmailLogsAPI: list(filters:, search_after:)
EmailLogsAPI->>EmailLogsAPI: build_list_query_params(filters, search_after)
EmailLogsAPI->>HTTPClient: GET /api/accounts/{id}/email_logs?filters...
HTTPClient->>APIServer: HTTP GET
APIServer-->>HTTPClient: 200 OK (messages, total_count, next_page_cursor)
HTTPClient-->>EmailLogsAPI: Response body
EmailLogsAPI->>Mapper: map response to EmailLogsListResponse
Mapper->>Mapper: build EmailLogMessage and nested EmailLogEvent(+details)
Mapper-->>EmailLogsAPI: EmailLogsListResponse
EmailLogsAPI-->>Client: return EmailLogsListResponse
sequenceDiagram
actor Client
participant EmailLogsAPI
participant HTTPClient as HTTP Client
participant APIServer as API Server
participant Mapper as Response Mapper
Client->>EmailLogsAPI: get(sending_message_id)
EmailLogsAPI->>HTTPClient: GET /api/accounts/{id}/email_logs/{message_id}
HTTPClient->>APIServer: HTTP GET
alt Message Found
APIServer-->>HTTPClient: 200 OK (message)
HTTPClient-->>EmailLogsAPI: Response body
EmailLogsAPI->>Mapper: map to EmailLogMessage
Mapper->>Mapper: build EmailLogEvent array and details
Mapper-->>EmailLogsAPI: EmailLogMessage
EmailLogsAPI-->>Client: return EmailLogMessage
else Message Not Found
APIServer-->>HTTPClient: 404 Not Found
HTTPClient-->>EmailLogsAPI: Error response
EmailLogsAPI-->>Client: raise Mailtrap::Error
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
spec/mailtrap/email_log_message_spec.rb (1)
27-29: Test intent says “all attributes” but excludes optional fields.Consider asserting
raw_message_urlandeventsexplicitly (even asnil) so the claim and coverage match.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@spec/mailtrap/email_log_message_spec.rb` around lines 27 - 29, The spec "it 'creates a message with all attributes'" currently uses expect(message).to have_attributes(attributes) but the attributes hash omits optional fields; update the test so the claim matches reality by adding raw_message_url and events to the asserted attributes (set them to nil if that's the expected value) or add explicit expectations like expect(message.raw_message_url).to be_nil and expect(message.events).to be_nil; refer to the test subject `message`, the example name, and the `attributes` hash when making the change.examples/email_logs_api.rb (1)
3-11: Consider reordering to favor environment variables as the primary approach.The example hardcodes credentials first, then shows the environment variable approach as a comment. For better security practices in example code, consider swapping these:
♻️ Suggested reordering
-account_id = 3229 -client = Mailtrap::Client.new(api_key: 'your-api-key') -email_logs = Mailtrap::EmailLogsAPI.new(account_id, client) - # Set your API credentials as environment variables # export MAILTRAP_API_KEY='your-api-key' # export MAILTRAP_ACCOUNT_ID=your-account-id -# -# email_logs = Mailtrap::EmailLogsAPI.new +email_logs = Mailtrap::EmailLogsAPI.new + +# Or manually pass credentials: +# account_id = 3229 +# client = Mailtrap::Client.new(api_key: 'your-api-key') +# email_logs = Mailtrap::EmailLogsAPI.new(account_id, client)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/email_logs_api.rb` around lines 3 - 11, Swap the example to use environment variables as the primary credential approach: instantiate Mailtrap::Client and Mailtrap::EmailLogsAPI using ENV['MAILTRAP_API_KEY'] and ENV['MAILTRAP_ACCOUNT_ID'] (or call Mailtrap::EmailLogsAPI.new with no args if that constructor reads ENV) at the top, and move the hardcoded account_id and Mailtrap::Client.new(api_key: 'your-api-key') example into a commented “alternative” section; update the adjacent comments to show export instructions and mention the hardcoded snippet as an optional fallback.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@lib/mailtrap/email_log_event_details.rb`:
- Around line 52-56: The build method in EmailLogEventDetails currently assumes
DETAIL_STRUCTS[event_type.to_s] exists and will raise NoMethodError when
event_type is nil or unknown; update EmailLogEventDetails.build to handle a
missing struct_class by checking the result of DETAIL_STRUCTS[event_type.to_s]
(and event_type.nil?) and either (a) return a sensible default/ fallback struct
(or a generic OpenStruct) populated with the sliced attrs, or (b) raise a clear
ArgumentError/RuntimeError with a descriptive message including the unknown
event_type; ensure you reference DETAIL_STRUCTS and struct_class in the change
so callers get a graceful/failing-but-descriptive behavior from
EmailLogEventDetails.build.
---
Nitpick comments:
In `@examples/email_logs_api.rb`:
- Around line 3-11: Swap the example to use environment variables as the primary
credential approach: instantiate Mailtrap::Client and Mailtrap::EmailLogsAPI
using ENV['MAILTRAP_API_KEY'] and ENV['MAILTRAP_ACCOUNT_ID'] (or call
Mailtrap::EmailLogsAPI.new with no args if that constructor reads ENV) at the
top, and move the hardcoded account_id and Mailtrap::Client.new(api_key:
'your-api-key') example into a commented “alternative” section; update the
adjacent comments to show export instructions and mention the hardcoded snippet
as an optional fallback.
In `@spec/mailtrap/email_log_message_spec.rb`:
- Around line 27-29: The spec "it 'creates a message with all attributes'"
currently uses expect(message).to have_attributes(attributes) but the attributes
hash omits optional fields; update the test so the claim matches reality by
adding raw_message_url and events to the asserted attributes (set them to nil if
that's the expected value) or add explicit expectations like
expect(message.raw_message_url).to be_nil and expect(message.events).to be_nil;
refer to the test subject `message`, the example name, and the `attributes` hash
when making the change.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: c132c193-ccee-4f99-a377-9cc692da37f6
📒 Files selected for processing (16)
README.mdexamples/email_logs_api.rblib/mailtrap.rblib/mailtrap/email_log_event.rblib/mailtrap/email_log_event_details.rblib/mailtrap/email_log_message.rblib/mailtrap/email_logs_api.rblib/mailtrap/email_logs_list_response.rbspec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_get/maps_response_data_to_EmailLogMessage_with_events_and_raw_message_url.ymlspec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_get/when_message_not_found/raises_error.ymlspec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_list/maps_response_data_to_EmailLogsListResponse_with_messages.ymlspec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_list/with_filters_and_search_after/sends_correct_query_params_and_maps_response_data_to_EmailLogsListResponse_with_messages.ymlspec/mailtrap/email_log_event_details_spec.rbspec/mailtrap/email_log_event_spec.rbspec/mailtrap/email_log_message_spec.rbspec/mailtrap/email_logs_api_spec.rb
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
lib/mailtrap/email_logs_api.rb (1)
104-110:⚠️ Potential issue | 🟠 MajorPrevent one unknown event type from aborting full response mapping.
At Lines 104-110,
EmailLogEventDetails.buildexceptions bubble up. If the API introduces a newevent_type,#list/#getcan fail entirely instead of returning the rest of the message data.Proposed fix
def build_events(events_array) Array(events_array).map do |e| + details = begin + EmailLogEventDetails.build(e[:event_type], e[:details] || {}) + rescue ArgumentError + nil + end + EmailLogEvent.new( event_type: e[:event_type], created_at: e[:created_at], - details: EmailLogEventDetails.build(e[:event_type], e[:details]) + details: details ) end end🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/mailtrap/email_logs_api.rb` around lines 104 - 110, build_events currently maps events_array and calls EmailLogEventDetails.build for each event which can raise and abort the whole mapping; modify build_events (the method that constructs EmailLogEvent instances) to rescue exceptions raised by EmailLogEventDetails.build for each individual event, log or record the error, and fall back to a safe default (e.g. nil or an UnknownEmailLogEventDetails placeholder) for the details so a single unknown/new event_type does not break the entire response; keep the rest of the EmailLogEvent construction unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@lib/mailtrap/email_log_event_details.rb`:
- Around line 53-58: The build method calls hash.slice(...) which will raise if
hash is nil; update EmailLogEventDetails.build to guard against nil details by
coercing the incoming hash to an empty hash before calling slice (e.g., replace
uses of hash.slice(...) with (hash || {}).slice(...) or assign hash = {} if
nil), keeping the existing lookup via DETAIL_STRUCTS and the subsequent
struct_class.new(**attrs) behavior; reference the build method and
DETAIL_STRUCTS to locate the change.
In `@spec/mailtrap/email_logs_api_spec.rb`:
- Around line 6-7: The spec is flaky because let(:account_id) uses ENV.fetch and
can diverge from the hardcoded 1_111_111 used later; change let(:account_id) in
spec/mailtrap/email_logs_api_spec.rb to a deterministic literal (e.g.,
1_111_111) so it matches the cassette/test expectations, and update any other
occurrences (the places referenced on Lines 55-56) to use the same constant
value to keep VCR cassette paths and recordings stable.
---
Duplicate comments:
In `@lib/mailtrap/email_logs_api.rb`:
- Around line 104-110: build_events currently maps events_array and calls
EmailLogEventDetails.build for each event which can raise and abort the whole
mapping; modify build_events (the method that constructs EmailLogEvent
instances) to rescue exceptions raised by EmailLogEventDetails.build for each
individual event, log or record the error, and fall back to a safe default (e.g.
nil or an UnknownEmailLogEventDetails placeholder) for the details so a single
unknown/new event_type does not break the entire response; keep the rest of the
EmailLogEvent construction unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: b8378af5-4a68-405f-8604-3c4db4a3514f
📒 Files selected for processing (16)
README.mdexamples/email_logs_api.rblib/mailtrap.rblib/mailtrap/email_log_event.rblib/mailtrap/email_log_event_details.rblib/mailtrap/email_log_message.rblib/mailtrap/email_logs_api.rblib/mailtrap/email_logs_list_response.rbspec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_get/maps_response_data_to_EmailLogMessage_with_events_and_raw_message_url.ymlspec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_get/when_message_not_found/raises_error.ymlspec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_list/maps_response_data_to_EmailLogsListResponse_with_messages.ymlspec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_list/with_filters_and_search_after/sends_correct_query_params_and_maps_response_data_to_EmailLogsListResponse_with_messages.ymlspec/mailtrap/email_log_event_details_spec.rbspec/mailtrap/email_log_event_spec.rbspec/mailtrap/email_log_message_spec.rbspec/mailtrap/email_logs_api_spec.rb
🚧 Files skipped from review as they are similar to previous changes (11)
- spec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_list/maps_response_data_to_EmailLogsListResponse_with_messages.yml
- lib/mailtrap/email_logs_list_response.rb
- spec/mailtrap/email_log_message_spec.rb
- lib/mailtrap/email_log_event.rb
- spec/mailtrap/email_log_event_details_spec.rb
- spec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_get/maps_response_data_to_EmailLogMessage_with_events_and_raw_message_url.yml
- spec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_list/with_filters_and_search_after/sends_correct_query_params_and_maps_response_data_to_EmailLogsListResponse_with_messages.yml
- lib/mailtrap/email_log_message.rb
- spec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_get/when_message_not_found/raises_error.yml
- README.md
- examples/email_logs_api.rb
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
spec/mailtrap/email_log_message_spec.rb (1)
4-22: Consider adding optional attributes to test coverage.The test attributes hash does not include
raw_message_urlandeventsfields, which are part ofEmailLogMessageaccording to the API response mapping. While these fields are optional (returned only from thegetendpoint), adding them to the test would ensure complete coverage of the DTO's initialization behavior.💡 Suggested addition
template_variables: {}, opens_count: 2, - clicks_count: 1 + clicks_count: 1, + raw_message_url: 'https://example.com/raw', + events: [] }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@spec/mailtrap/email_log_message_spec.rb` around lines 4 - 22, The spec's attributes hash used to initialize EmailLogMessage is missing optional fields raw_message_url and events; update the let(:attributes) hash in spec/mailtrap/email_log_message_spec.rb to include raw_message_url (string URL) and events (array of event hashes or empty array) so EmailLogMessage initialization and its handling of optional API response fields are covered by the test.spec/mailtrap/email_log_event_details_spec.rb (1)
3-62: Consider adding test coverage for remaining event types.The tests cover
delivery,click, andbounceevent types, but based on the implementation context, there are additional event types:open,spam,unsubscribe,reject, andsuspension. While the current tests demonstrate the pattern works, adding at least one test for each struct type would provide more comprehensive coverage and document the expected attributes for each.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@spec/mailtrap/email_log_event_details_spec.rb` around lines 3 - 62, Add tests for the remaining event types by extending the Mailtrap::EmailLogEventDetails spec: for each event_type 'open', 'spam', 'unsubscribe', 'reject', and 'suspension' call described_class.build(event_type, payload) and assert the returned object is the appropriate struct (described_class::Open, ::Spam, ::Unsubscribe, ::Reject, ::Suspension) and has the expected attributes for that type (mirror the pattern used for Delivery/Click/Bounce tests), using be_a(...) and have_attributes(...) to verify attribute names and example values; keep the tests consistent with existing examples so they validate .build behavior for all known DETAIL_STRUCTS.lib/mailtrap/email_logs_api.rb (1)
13-13: Unusedresponse_classassignment.The
response_classis set toEmailLogMessagebut is never used since this class implements customlistandgetmethods instead of usingbase_listandbase_getfromBaseAPI. Consider removing this line to avoid confusion, or add a comment explaining if it's intended for future use or external introspection.🧹 Proposed removal
class EmailLogsAPI include BaseAPI - self.response_class = EmailLogMessage - # Lists email logs with optional filters and cursor-based pagination.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/mailtrap/email_logs_api.rb` at line 13, The file sets response_class = EmailLogMessage but that assignment is unused because the class implements custom list and get methods instead of leveraging BaseAPI's base_list/base_get; remove the unused response_class = EmailLogMessage line from the EmailLogsAPI class (or alternatively add a concise comment above it indicating it's intentional/for external introspection) so the declaration no longer confuses readers — search for response_class, EmailLogMessage, list, get, BaseAPI, base_list and base_get in the EmailLogsAPI implementation to locate and apply the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@lib/mailtrap/email_logs_api.rb`:
- Around line 104-112: The build_events method can pass nil details into
EmailLogEventDetails.build causing a NoMethodError; update build_events to
defensively pass an empty hash when e[:details] is nil (i.e., call
EmailLogEventDetails.build(e[:event_type], e[:details] || {})). Locate the
build_events function and change the details argument before constructing
EmailLogEvent so EmailLogEventDetails.build always receives a Hash.
---
Nitpick comments:
In `@lib/mailtrap/email_logs_api.rb`:
- Line 13: The file sets response_class = EmailLogMessage but that assignment is
unused because the class implements custom list and get methods instead of
leveraging BaseAPI's base_list/base_get; remove the unused response_class =
EmailLogMessage line from the EmailLogsAPI class (or alternatively add a concise
comment above it indicating it's intentional/for external introspection) so the
declaration no longer confuses readers — search for response_class,
EmailLogMessage, list, get, BaseAPI, base_list and base_get in the EmailLogsAPI
implementation to locate and apply the change.
In `@spec/mailtrap/email_log_event_details_spec.rb`:
- Around line 3-62: Add tests for the remaining event types by extending the
Mailtrap::EmailLogEventDetails spec: for each event_type 'open', 'spam',
'unsubscribe', 'reject', and 'suspension' call described_class.build(event_type,
payload) and assert the returned object is the appropriate struct
(described_class::Open, ::Spam, ::Unsubscribe, ::Reject, ::Suspension) and has
the expected attributes for that type (mirror the pattern used for
Delivery/Click/Bounce tests), using be_a(...) and have_attributes(...) to verify
attribute names and example values; keep the tests consistent with existing
examples so they validate .build behavior for all known DETAIL_STRUCTS.
In `@spec/mailtrap/email_log_message_spec.rb`:
- Around line 4-22: The spec's attributes hash used to initialize
EmailLogMessage is missing optional fields raw_message_url and events; update
the let(:attributes) hash in spec/mailtrap/email_log_message_spec.rb to include
raw_message_url (string URL) and events (array of event hashes or empty array)
so EmailLogMessage initialization and its handling of optional API response
fields are covered by the test.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 1082f9c5-ad29-4678-bde9-9259a6a00386
📒 Files selected for processing (17)
CHANGELOG.mdREADME.mdexamples/email_logs_api.rblib/mailtrap.rblib/mailtrap/email_log_event.rblib/mailtrap/email_log_event_details.rblib/mailtrap/email_log_message.rblib/mailtrap/email_logs_api.rblib/mailtrap/email_logs_list_response.rbspec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_get/maps_response_data_to_EmailLogMessage_with_events_and_raw_message_url.ymlspec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_get/when_message_not_found/raises_error.ymlspec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_list/maps_response_data_to_EmailLogsListResponse_with_messages.ymlspec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_list/with_filters_and_search_after/sends_correct_query_params_and_maps_response_data_to_EmailLogsListResponse_with_messages.ymlspec/mailtrap/email_log_event_details_spec.rbspec/mailtrap/email_log_event_spec.rbspec/mailtrap/email_log_message_spec.rbspec/mailtrap/email_logs_api_spec.rb
🚧 Files skipped from review as they are similar to previous changes (11)
- spec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_get/maps_response_data_to_EmailLogMessage_with_events_and_raw_message_url.yml
- README.md
- examples/email_logs_api.rb
- lib/mailtrap/email_log_message.rb
- spec/mailtrap/email_log_event_spec.rb
- lib/mailtrap.rb
- spec/mailtrap/email_logs_api_spec.rb
- spec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_get/when_message_not_found/raises_error.yml
- lib/mailtrap/email_log_event_details.rb
- spec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_list/maps_response_data_to_EmailLogsListResponse_with_messages.yml
- lib/mailtrap/email_log_event.rb
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (2)
lib/mailtrap/email_log_event_details.rb (1)
53-58:⚠️ Potential issue | 🟠 MajorGuard
hash.sliceagainst nil details to avoid runtime crashes.At Line 57,
hash.slice(...)will raise whendetailsis nil. Coerce to{}before slicing.Proposed fix
def self.build(event_type, hash) struct_class = DETAIL_STRUCTS[event_type.to_s] raise ArgumentError, "Unknown event_type: #{event_type.inspect}" unless struct_class - attrs = hash.slice(*struct_class.members) + details_hash = hash.is_a?(Hash) ? hash : {} + attrs = details_hash.slice(*struct_class.members) struct_class.new(**attrs) end#!/bin/bash # Verify whether API fixtures contain null details and confirm current call-path behavior. set -euo pipefail echo "1) Look for null event details in VCR fixtures:" rg -n '"details"\s*:\s*null' spec/fixtures/vcr_cassettes || true echo echo "2) Confirm EmailLogsAPI passes event details directly into builder:" rg -n -C2 'EmailLogEventDetails\.build\(e\[:event_type\], e\[:details\]\)' lib/mailtrap/email_logs_api.rb echo echo "3) Confirm builder currently slices hash without nil coercion:" rg -n -C2 'def self\.build|hash\.slice' lib/mailtrap/email_log_event_details.rb🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/mailtrap/email_log_event_details.rb` around lines 53 - 58, The build method in EmailLogEventDetails uses hash.slice(...) which will raise if the passed-in hash is nil; update the code in self.build to coerce the incoming hash/details to an empty hash (e.g., using hash = (hash || {}) or hash.to_h) before calling slice so attrs = hash.slice(*struct_class.members) is safe; ensure you still raise the ArgumentError when DETAIL_STRUCTS[event_type.to_s] is missing and construct the struct_class.new(**attrs) as before.spec/mailtrap/email_logs_api_spec.rb (1)
6-7:⚠️ Potential issue | 🟡 MinorMake this VCR spec deterministic by removing ENV-driven IDs in expectations.
Line 6 can drift from the hardcoded path on Lines 55-56, which can cause cassette mismatches/flaky specs. Use a fixed
account_idin this file and interpolate it in the expectation path.Proposed fix
- let(:account_id) { ENV.fetch('MAILTRAP_ACCOUNT_ID', 1_111_111) } - let(:client) { Mailtrap::Client.new(api_key: ENV.fetch('MAILTRAP_API_KEY', 'local-api-key')) } + let(:account_id) { 1_111_111 } + let(:client) { Mailtrap::Client.new(api_key: 'local-api-key') } @@ - expect(client).to have_received(:get).with( - '/api/accounts/1111111/email_logs', + expect(client).to have_received(:get).with( + "/api/accounts/#{account_id}/email_logs", {Also applies to: 55-56
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@spec/mailtrap/email_logs_api_spec.rb` around lines 6 - 7, The spec is non-deterministic because account_id is pulled from ENV; replace the ENV.fetch('MAILTRAP_ACCOUNT_ID', 1_111_111) usage by setting a fixed literal account_id (e.g. 1111111) in the spec and update any expectations that build the request path (the expectation that references the path using account_id around the Mailtrap::Client call) to interpolate that same fixed account_id so the VCR cassette path matches deterministically; ensure the let(:account_id) value and the expectation path referencing account_id (used with client/EmailLogs API requests) use the identical fixed value.
🧹 Nitpick comments (1)
spec/mailtrap/email_log_message_spec.rb (1)
4-29: This spec doesn't cover the full DTO surface.
raw_message_urlandeventsare part ofMailtrap::EmailLogMessage, but they aren't included inattributes, so the example name currently overstates what it verifies. Add them here or rename the example to reflect a partial attribute check.♻️ Suggested update
template_variables: {}, opens_count: 2, - clicks_count: 1 + clicks_count: 1, + raw_message_url: 'https://example.com/raw/test-message.eml', + events: [ + Mailtrap::EmailLogEvent.new( + event_type: 'delivery', + created_at: '2025-01-15T10:30:01Z' + ) + ]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@spec/mailtrap/email_log_message_spec.rb` around lines 4 - 29, The spec's attributes hash used to initialize Mailtrap::EmailLogMessage is missing raw_message_url and events, so change the attributes used by described_class.new (the let(:attributes) hash) to include keys for raw_message_url and events with representative values, ensuring the subject(:message) test can truly assert all DTO fields via expect(message).to have_attributes(attributes); alternatively, if you prefer not to add them, update the example description (the it string) to indicate it checks only a subset of attributes rather than "all attributes".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@examples/email_logs_api.rb`:
- Around line 34-35: The second-page call drops the original filters so
pagination no longer uses the same result set; update the follow-up call to pass
both the original filters and the cursor by calling email_logs.list with filters
plus search_after: response.next_page_cursor (use the same filters
object/variable you used in the first request) so the request includes
filters[<field>][operator], filters[<field>][value] alongside search_after;
locate the pagination example that assigns response and modify the subsequent
email_logs.list invocation to include the filters parameter together with
search_after.
- Line 1: Add the missing stdlib require so Time#iso8601 is available: at the
top of examples/email_logs_api.rb, alongside the existing require 'mailtrap',
add require 'time' so the calls to Time.now.utc.iso8601 (used around the
Time.now.utc.iso8601 occurrences) won’t raise NoMethodError when the example
runs.
In `@lib/mailtrap/email_log_message.rb`:
- Around line 14-18: Update the YARD attribute docs for the nullable hash fields
so the DTO matches actual responses: change the `@attr_reader` types for
custom_variables and template_variables from "Hash" to "Hash, nil" in
email_log_message.rb (the attribute doc comments for custom_variables and
template_variables), leaving other annotations (e.g., template_id) unchanged.
---
Duplicate comments:
In `@lib/mailtrap/email_log_event_details.rb`:
- Around line 53-58: The build method in EmailLogEventDetails uses
hash.slice(...) which will raise if the passed-in hash is nil; update the code
in self.build to coerce the incoming hash/details to an empty hash (e.g., using
hash = (hash || {}) or hash.to_h) before calling slice so attrs =
hash.slice(*struct_class.members) is safe; ensure you still raise the
ArgumentError when DETAIL_STRUCTS[event_type.to_s] is missing and construct the
struct_class.new(**attrs) as before.
In `@spec/mailtrap/email_logs_api_spec.rb`:
- Around line 6-7: The spec is non-deterministic because account_id is pulled
from ENV; replace the ENV.fetch('MAILTRAP_ACCOUNT_ID', 1_111_111) usage by
setting a fixed literal account_id (e.g. 1111111) in the spec and update any
expectations that build the request path (the expectation that references the
path using account_id around the Mailtrap::Client call) to interpolate that same
fixed account_id so the VCR cassette path matches deterministically; ensure the
let(:account_id) value and the expectation path referencing account_id (used
with client/EmailLogs API requests) use the identical fixed value.
---
Nitpick comments:
In `@spec/mailtrap/email_log_message_spec.rb`:
- Around line 4-29: The spec's attributes hash used to initialize
Mailtrap::EmailLogMessage is missing raw_message_url and events, so change the
attributes used by described_class.new (the let(:attributes) hash) to include
keys for raw_message_url and events with representative values, ensuring the
subject(:message) test can truly assert all DTO fields via expect(message).to
have_attributes(attributes); alternatively, if you prefer not to add them,
update the example description (the it string) to indicate it checks only a
subset of attributes rather than "all attributes".
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 37c8c80a-88f4-4028-a95a-0a2a7c8adb68
📒 Files selected for processing (17)
CHANGELOG.mdREADME.mdexamples/email_logs_api.rblib/mailtrap.rblib/mailtrap/email_log_event.rblib/mailtrap/email_log_event_details.rblib/mailtrap/email_log_message.rblib/mailtrap/email_logs_api.rblib/mailtrap/email_logs_list_response.rbspec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_get/maps_response_data_to_EmailLogMessage_with_events_and_raw_message_url.ymlspec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_get/when_message_not_found/raises_error.ymlspec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_list/maps_response_data_to_EmailLogsListResponse_with_messages.ymlspec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_list/with_filters_and_search_after/sends_correct_query_params_and_maps_response_data_to_EmailLogsListResponse_with_messages.ymlspec/mailtrap/email_log_event_details_spec.rbspec/mailtrap/email_log_event_spec.rbspec/mailtrap/email_log_message_spec.rbspec/mailtrap/email_logs_api_spec.rb
✅ Files skipped from review due to trivial changes (1)
- spec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_get/when_message_not_found/raises_error.yml
🚧 Files skipped from review as they are similar to previous changes (5)
- spec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_list/maps_response_data_to_EmailLogsListResponse_with_messages.yml
- CHANGELOG.md
- lib/mailtrap.rb
- spec/fixtures/vcr_cassettes/Mailtrap_EmailLogsAPI/_list/with_filters_and_search_after/sends_correct_query_params_and_maps_response_data_to_EmailLogsListResponse_with_messages.yml
- spec/mailtrap/email_log_event_details_spec.rb
Motivation
Add support for Email Logs API
Summary by CodeRabbit
New Features
Documentation
Examples
Tests